﻿//================================================================
// Copyright (C) 2012 新天华通 版权所有。 
// 文件功能描述: 哈希算法类，下面三个哈希类都继承自哈希算法基类，获取int哈希值方式如：
//               BitConverter.ToUInt32(new ModifiedFNV1_32(). ComputeHash(Encoding.UTF8.GetBytes("王华")), 0);
//               哈希函数是现代密码系统的基础。这些函数将任意长度的二进制字符串映射为固定长度的小二进制字符串（称为哈希值）。
//               加密哈希函数有这样一个属性：在计算时不可能将两个不同的输入通过哈希算法取为相同的值。
//               哈希值用作表示大量数据的固定大小的唯一值。如果相应的数据也匹配，则两个数据集的哈希应该匹配。
//               BitConverter 类用于处理值类型与位、字节...之间的转换。    

//               SHA512 哈希算法可以使用内置的 SHA512Managed Arithmetic = new SHA512Managed()，不过返回64位字节
// 创建标识：王华  2012-04-26
//================================================================
using System;
using System.Security.Cryptography;

namespace Chada.Infrastructure.Utility.DEncrypt
{
    /// <summary>
    /// FNV(Fowler-Noll-Vo)哈希算法，变体 1, 32-bit version.
    /// </summary>
    public class FNV1_32 : HashAlgorithm
    {
        private static readonly uint FNV_prime = 16777619;
        private static readonly uint offset_basis = 2166136261;

        protected uint hash;

        public FNV1_32()
        {
            base.HashSizeValue = 32;  // 设置哈希值大小为32位，即4个字节
        }

        public override void Initialize()
        {
            hash = offset_basis;
        }

        protected override void HashCore(byte[] array, int ibStart, int cbSize)
        {
            int length = ibStart + cbSize;
            for (int i = ibStart; i < length; i++)
            {
                hash = (hash * FNV_prime) ^ array[i];
            }
        }

        protected override byte[] HashFinal()
        {
            return BitConverter.GetBytes(hash);
        }
    }

    /// <summary>
    /// FNV(Fowler-Noll-Vo)哈希算法, 变体 1a, 32-bit version.
    /// </summary>
    public class FNV1a_32 : HashAlgorithm
    {
        private static readonly uint FNV_prime = 16777619;
        private static readonly uint offset_basis = 2166136261;

        protected uint hash;

        public FNV1a_32()
        {
            base.HashSizeValue = 32;
        }

        public override void Initialize()
        {
            hash = offset_basis;
        }

        protected override void HashCore(byte[] array, int ibStart, int cbSize)
        {
            int length = ibStart + cbSize;
            for (int i = ibStart; i < length; i++)
            {
                hash = (hash ^ array[i]) * FNV_prime;  //与 FNV1_32 类就这里不同 
            }
        }

        protected override byte[] HashFinal()
        {
            return BitConverter.GetBytes(hash);
        }
    }

    /// <summary>
    /// FNV(Fowler-Noll-Vo)哈希算法,修改的, 32-bit version.
    /// </summary>
    public class ModifiedFNV1_32 : FNV1_32
    {
        protected override byte[] HashFinal()
        {
            hash += hash << 13;
            hash ^= hash >> 7;
            hash += hash << 3;
            hash ^= hash >> 17;
            hash += hash << 5;
            return BitConverter.GetBytes(hash);
        }
    }
}